
Place = function(spec) {
    $.extend(this, spec);
    if (this.schedule) {
        this.schedule = new Schedule(this.schedule);
    }
};

Place.prototype = {
    type: 'Place',

    findLocation: function(source, callback) {
        if (!this.address) {
            var sourceLatlng = new google.maps.LatLng(source.latitude, source.longitude);
            var div = $(document.body).append('<div style="display: none;"></div>').children(':last');
            var map = new google.maps.Map(div.get(0), {
                mapTypeId: google.maps.MapTypeId.ROADMAP,
                center: sourceLatlng,
                zoom: 15
            });
            var request = {
                location: sourceLatlng,
                radius: 16093, // 10 miles
                name: this.name
            };
            var self = this;
            var service = new google.maps.places.PlacesService(map);
            service.search(request, function(results, status) {
                console.log('place search for', self.name, 'yielded', results);
                div.remove();
                var success = status == google.maps.places.PlacesServiceStatus.OK;
                if (success && results.length) {
                    var min = Infinity;
                    var minResult = null;
                    $.each(results, function(_, result) {
                        var l = result.geometry.location;
                        var d = google.maps.geometry.spherical.computeDistanceBetween(l, sourceLatlng);
                        if (d < min) {
                            min = d;
                            minResult = result;
                        }
                    });
                    self.address = minResult.vicinity;
                    self.findLocationWithAddress(callback);
                } else {
                    callback(false);
                }
            });
        } else {
            this.findLocationWithAddress(callback);
        }
    },

    findLocationWithAddress: function(callback) {
        var geocoder = new google.maps.Geocoder();
        var self = this;
        geocoder.geocode({'address': this.address}, function(results, status) {
            var success = status == google.maps.GeocoderStatus.OK;
            if (success) {
                var latitude = results[0].geometry.location.lat();
                var longitude = results[0].geometry.location.lng();
                self.geolocation = new LatLng({
                    latitude: latitude,
                    longitude: longitude
                });
            }
            callback(success);
        });
    }
};

Place.parse = function(place) {
    if (place.type == Place.prototype.type) {
        return place;
    }
    return new Place(place);
};
